function deepClone(target, hash = new WeakMap()) {
  if (typeof target !== 'object' || target === null) return target
  let obj = Array.isArray(target) ? [] : {}
  if (hash.has(target)) {
    return hash.get(target)
  }
  hash.set(target, obj)
  Reflect.ownKeys(target).forEach(key => {
    if (typeof target[key] !== 'object' || target[key] === null) obj[key] = target[key]
    else {
      obj[key] = deepClone(target[key], hash)
    }
  })
}